<!--
@license
Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<link rel="import" href="../tf-imports/polymer.html" />
<link rel="import" href="../tf-hparams-query-pane/tf-hparams-query-pane.html" />
<link
  rel="import"
  href="../tf-hparams-sessions-pane/tf-hparams-sessions-pane.html"
/>
<link
  rel="import"
  href="../tf-hparams-google-analytics-tracker/tf-hparams-google-analytics-tracker.html"
/>
<link rel="import" href="../tf-imports/vaadin-split-layout.html" />
<link rel="import" href="../tf-imports/lodash.html" />

<!-- The entry point into the hparams plugin frontend.
A container for two sub-elements:
1. The query-pane encapsulated by the tf-hparams-query-pane element. This
element issues queries to the backend to get a list of session groups. It has
controls to allow the user to specify filters and sorting options in the
issued-query. The actual filtering and sorting is done by the backend.
2. The session-pane encapsulated by the tf-hparams-session-pane element. This
element displays multiple tabs--each providing a "view" of the list of session
groups. Example of views are a table-view and a parallel-coordinate view.

TODO(erez): Add aggregation of repeated trials.
-->
<dom-module id="tf-hparams-main">
  <template>
    <vaadin-split-layout>
      <div class="sidebar" slot="sidebar">
        <tf-hparams-query-pane
          id="query-pane"
          backend="[[backend]]"
          experiment-name="[[experimentName]]"
          configuration="{{_configuration}}"
          session-groups="{{_sessionGroups}}"
        >
        </tf-hparams-query-pane>
      </div>
      <div class="center" slot="center">
        <tf-hparams-sessions-pane
          id="sessions-pane"
          backend="[[backend]]"
          help-url="[[helpUrl]]"
          bug-report-url="[[bugReportUrl]]"
          experiment-name="[[experimentName]]"
          configuration="[[_configuration]]"
          session-groups="[[_sessionGroups]]"
        >
        </tf-hparams-sessions-pane>
      </div>
    </vaadin-split-layout>
    <tf-hparams-google-analytics-tracker
      id="tracker"
      tracking-id="[[trackingId]]"
      name="tf_hparams"
    >
    </tf-hparams-google-analytics-tracker>

    <style>
      vaadin-split-layout {
        width: 100%;
      }

      .sidebar {
        width: 20%;
        height: 100%;
        overflow: auto;
        flex-grow: 0;
        flex-shrink: 0;
        min-width: 10%;
      }

      .center {
        height: 100%;
        overflow-y: auto;
        flex-grow: 1;
        flex-shrink: 1;
        width: 80%;
      }

      :host {
        display: flex;
        flex-direction: row;
        height: 100%;
        width: 100%;
      }
    </style>
  </template>

  <script>
    'use strict';
    Polymer({
      is: 'tf-hparams-main',
      properties: {
        // An object for making HParams API requests to the backend.
        backend: Object,
        // The experimentName to pass to the 'GetExperiment' API call.
        experimentName: String,
        // The google-analytics tracking-id to use. If not specified or empty
        // tracking will be disabled.
        trackingId: String,
        // The URL to use for the help button.
        helpUrl: String,
        // The URL to use for the bug-report button.
        bugReportUrl: String,

        _configuration: Object,
        _sessionGroups: Array,

        // A throttled function for sending events to GA analytics at a bounded
        // rate. We use a property here so that each tf-hparams-main element
        // will have its own throttler, rather than using a global one.
        _throttledSendEventToGA: {
          type: Function,
          value: () =>
            _.throttle(
              function() {
                this._handleGAEvent({
                  detail: {
                    hitType: 'event',
                    eventCategory: 'UserInteraction',
                    eventLabel: 'Experiment: ' + this.experimentName,
                  },
                });
              },
              60000 /* wait = 60000 milliseconds or 1 minute */,
              {leading: true} /* Call on the leading edge of wait period. */
            ),
        },
      },

      // Listen for google-analytics-tracking events from child elements
      // and dispatch them to the tracker.
      listeners: {
        mousemove: '_sendEventToGA',
        tap: '_sendEventToGA',
        'google-analytics-tracking': '_handleGAEvent',
      },

      attached() {
        // We don't use 'ready()', since empirically, ready() can be called
        // before 'trackingId' is set.
        this._handleGAEvent({detail: {hitType: 'pageview'}});
      },

      // This can be called to refresh the plugin.
      reload() {
        this.$['query-pane'].reload();
      },

      _sendEventToGA() {
        this._throttledSendEventToGA(this);
      },

      _handleGAEvent(event) {
        this.$.tracker.handleEvent(event);
      },
    });
  </script>
</dom-module>
